package com.share.device.emqx.factory.Impl;

import com.share.device.emqx.annotation.GuiguEmqx;
import com.share.device.emqx.factory.MessageHandlerFactory;
import com.share.device.emqx.handler.MassageHandler;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;


/**
 * 消息处理工厂类
 *  工厂模式实现了原理，通过topic获取对应的处理类
 *  获取所有MassageHandler.class 的bean对象
 *  然后遍历获取对应的处理类，通过注解获取对应的topic
 *  然后将topic作为key，处理类作为value保存在map中
 *  然后就可以通过不同的topic获取对应的处理类，
 *  使用getMassageHandler()获取对应的处理类
 * 例如：
 *  MessageHandlerFactory.getMassageHandler(topic).handleMessage(message);
 *  获取对应的处理类, 然后调用对应的处理类的handleMessage()方法处理消息
 */
@Service
public class MessageHandlerFactoryImpl implements MessageHandlerFactory, ApplicationContextAware {

    private Map<String, MassageHandler> handlerMap = new HashMap<>();

    /**
     * 初始化bean对象
     *
     * @param ioc
     */
    @Override
    public void setApplicationContext(ApplicationContext ioc) {
        // 获取对象
        Map<String, MassageHandler> beanMap = ioc.getBeansOfType(MassageHandler.class);
        for (MassageHandler massageHandler : beanMap.values()) {
            GuiguEmqx guiguEmqx = AnnotatedElementUtils.findAllMergedAnnotations(massageHandler.getClass(), GuiguEmqx.class).iterator().next();
            if (null != guiguEmqx) {
                String topic = guiguEmqx.topic();
                // 初始化到map
                handlerMap.put(topic, massageHandler);
            }
        }
    }

    @Override
    public MassageHandler getMassageHandler(String topic) {
        return handlerMap.get(topic);
    }

}
